package common.server.utils;


import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import common.server.http.NameValuePair;

public class HttpClient {

	public static final String FORM_URLENCODED = "application/x-www-form-urlencoded";
	public static final String FORM_DATA = "multipart/form-data";
	public static final String APPLICATION_JSON = "application/json";

	private Log logger = LogFactory.getLog(getClass());

	private int connectTimeout;
	private int readTimeout;
	private Proxy proxy;
	private CookieStore cookieStore;

	private boolean autoRedirect = true;

	public boolean isAutoRedirect() {
		return autoRedirect;
	}

	public void setAutoRedirect(boolean autoRedirect) {
		this.autoRedirect = autoRedirect;
	}

	public HttpClient(Proxy proxy, CookieStore cookieStore, int connectTimeout, int readTimeout) {

		this.connectTimeout = connectTimeout;
		this.readTimeout = readTimeout;
		this.proxy = proxy;

		if (cookieStore == null) {
			cookieStore = new CookieStore();
		}
		this.cookieStore = cookieStore;
	}

	/**
	 * GET
	 * 
	 * @param url
	 * @param headers
	 * @param autoRedirect
	 * @return
	 */
	public HttpResponse get(String url, Map<String, String> headers) {

		HttpURLConnection connection = null;
		try {
			connection = HttpTools.openConnection(url, proxy, HttpTools.GET, connectTimeout, readTimeout, autoRedirect, headers, cookieStore);
			connection.connect();
			return HttpTools.getResponse(this, connection, cookieStore);
		} catch (Exception e) {
			logger.warn(e.getMessage() + " - " + url);
			throw new RuntimeException(e);
		}
	}

	/**
	 * POST
	 * 
	 * @param url
	 * @param content
	 * @param headers
	 * @return
	 */
	public HttpResponse post(String url, Map<String, String> headers, byte[] content) {

		HttpURLConnection connection = null;
		try {
			connection = HttpTools.openConnection(url, proxy, HttpTools.POST, connectTimeout, readTimeout, autoRedirect, headers, cookieStore);
			connection.connect();

			OutputStream os = connection.getOutputStream();
			try {
				os.write(content);
				os.flush();
			} finally {
				try {
					os.close();
				} catch (Exception e) {
				}
			}

			return HttpTools.getResponse(this, connection, cookieStore);
		} catch (Exception e) {
			logger.warn(e.getMessage() + " - " + url);
			throw new RuntimeException(e);
		}
	}

	/**
	 * 发送字符串
	 * 
	 * @param url
	 * @param headers
	 * @param contentType
	 * @param parameters
	 * @param parameterEncoding
	 * @return
	 */
	public HttpResponse post(String url, Map<String, String> headers, String contentType, String parameters, String parameterEncoding) {

		if (StringUtils.isEmpty(contentType)) {
			contentType = FORM_URLENCODED;
		}
		if (StringUtils.isEmpty(parameterEncoding)) {
			parameterEncoding = "utf-8";
		}
		if (headers == null) {
			headers = new HashMap<String, String>();
		}
		headers.put("Content-type", contentType + ";charset=" + parameterEncoding);

		byte[] content = parameters == null ? new byte[0] : StringUtils.getBytes(parameters, parameterEncoding);
		return post(url, headers, content);
	}

	/**
	 * 发送普通表单数据
	 * 
	 * @param url
	 * @param headers
	 * @param parameters
	 * @param parameterEncoding
	 * @return
	 */
	public HttpResponse post(String url, Map<String, String> headers, List<NameValuePair<String>> parameters, String parameterEncoding) {
		StringBuilder content = new StringBuilder();
		if (parameters != null) {
			for (NameValuePair<String> nv : parameters) {
				if (content.length() > 0) {
					content.append("&");
				}
				content.append(nv.getKey() + "=" + nv.getValue());
			}
		}
		return post(url, headers, FORM_URLENCODED, content.toString(), parameterEncoding);
	}

	/**
	 * 发送普通表单数据
	 * 
	 * @param url
	 * @param headers
	 * @param parameters
	 * @param parameterEncoding
	 * @return
	 */
	public HttpResponse post(String url, Map<String, String> headers, Map<String, String> parameters, String parameterEncoding) {
		List<NameValuePair<String>> nvs = new ArrayList<NameValuePair<String>>();
		if (parameters != null) {
			for (String key : parameters.keySet()) {
				nvs.add(new NameValuePair<String>(key, parameters.get(key)));
			}
		}
		return post(url, headers, nvs, parameterEncoding);
	}

}
